package com.youlai.quarkus.system.security.jwt;

import com.youlai.quarkus.system.common.exception.BusinessException;
import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.credential.TokenCredential;
import io.quarkus.security.identity.AuthenticationRequestContext;
import io.quarkus.security.identity.IdentityProvider;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.request.TokenAuthenticationRequest;
import io.smallrye.mutiny.Uni;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.Optional;

/**
 *  JWT token 管理器
 *
 * @author haoxr
 * @since 2023/9/13
 */

@RequiredArgsConstructor
@ApplicationScoped
@Slf4j
public class JwtAuthenticationProvider implements IdentityProvider<TokenAuthenticationRequest> {

    private final JwtTokenProvider jwtTokenProvider;

    @Override
    public Class<TokenAuthenticationRequest> getRequestType() {
        return TokenAuthenticationRequest.class;
    }

    @Override
    public Uni<SecurityIdentity> authenticate(TokenAuthenticationRequest request,
                                              AuthenticationRequestContext context) {
        TokenCredential credential = request.getToken();
        String token = credential.getToken();
        try {
            if (token != null && jwtTokenProvider.validateToken(token)) {
//                return Uni.createFrom().item(jwtTokenProvider.getAuthentication(token));
                return jwtTokenProvider.getAuthentication(token,context);
            }
        } catch (BusinessException ex) {
            log.error("authentication failed : ", ex);
            return Uni.createFrom().failure(new AuthenticationFailedException("authentication failed"));
        }
        return Uni.createFrom().optional(Optional.empty());
    }

}
